﻿/*
 * This software is the confidential and proprietary
 * information of NetBay
 * Such confidential information should not be disclosed
 * NetBay copyright(c) 2010
 */

#region Using
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel.DomainServices.Server;
#endregion

namespace NetBay.Core.BusinessEntities
{
    /// <summary>
    /// Class handle a item entity
    /// </summary>
    [DataContract]
    [Serializable]
    public abstract class ItemEntity
    {
        /// <summary>
        /// Key of item
        /// </summary>
        private Guid m_strKey;
        [Key]
        [DataMember]
        public Guid Key
        {
            get { return m_strKey; }
            /*private*/ set { m_strKey = value; }
        }

        /// <summary>
        /// Foreign key of item (usage for father's class)
        /// </summary>
        private Guid m_strForeignKey;
        [DataMember]
        public Guid ForeignKey
        {
            get { return m_strForeignKey; }
            set { m_strForeignKey = value; }
        }

        /// <summary>
        /// Foreign key of item (usage for this class)
        /// </summary>
        private Guid m_strForeignKey1;
        [DataMember]
        public Guid ForeignKey1
        {
            get { return m_strForeignKey1; }
            set { m_strForeignKey1 = value; }
        }

        /// <summary>
        /// Foreign key n°2 of item (usage for this class)
        /// </summary>
        private Guid m_strForeignKey2;
        [DataMember]
        public Guid ForeignKey2
        {
            get { return m_strForeignKey2; }
            set { m_strForeignKey2 = value; }
        }

        /// <summary>
        /// Foreign key n°3 of item (usage for this class)
        /// </summary>
        private Guid m_strForeignKey3;
        [DataMember]
        public Guid ForeignKey3
        {
            get { return m_strForeignKey3; }
            set { m_strForeignKey3 = value; }
        }

        /// <summary>
        /// Affect the foreign key to whole collection's element to a key
        /// </summary>
        /// <param name="p_ieCollection">Collection of ItemEntity</param>
        /// <param name="p_strKey">key to affect</param>
        public static void SetForeignKey(IEnumerable<ItemEntity> p_ieCollection, Guid p_strKey)
        {
            foreach (ItemEntity l_ieItem in p_ieCollection)
            {
                l_ieItem.ForeignKey = p_strKey;
            }
        }

        /// <summary>
        /// Affect the foreign key to whole collection's element to a key
        /// </summary>
        /// <param name="p_ieCollection">Collection of ItemEntity</param>
        /// <param name="p_strKey">key to affect</param>
        public static void SetForeignKey1(IEnumerable<ItemEntity> p_ieCollection, Guid p_strKey)
        {
            foreach (ItemEntity l_ieItem in p_ieCollection)
            {
                l_ieItem.ForeignKey1 = p_strKey;
            }
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public ItemEntity()
        {
            Key = Guid.NewGuid();
        }

        /// <summary>
        /// All items must implement the clonage function
        /// </summary>
        /// <returns>new instance of a copy for this instance</returns>
        public abstract object Clone();
    }

    #region Exemple
    //[DataContract]
    //public class ClassDerivate2 //: ClassBase
    //{
    //    [Key]
    //    [DataMember]
    //    public string CompanyName { get; set; }

    //    [DataMember]
    //    public int ClasseDerivateAddressId { get; set; }

    //    [DataMember]
    //    public string CountryName { get; set; }

    //    [Include]
    //    //[Association("CompanyAddress", "ClasseDerivateAddressId", "AddressId", IsForeignKey=true)]
    //    [Association("CompanyAddress", "CompanyName", "CompanyName")]
    //    public List<Address> MyAddress { get; set; }
    //    //public Address MyAddress { get; set; }
    //}
    
    [DataContract]
    [KnownType(typeof(UserEntity))]
    [KnownType(typeof(GroupEntity))]
    public abstract class ReturnObjectEntity : ItemEntity
    {
        #region Enum
        /// <summary>
        /// List of Error codes
        /// </summary>
        public enum ErrorCodes
        {
            /// <summary>
            /// Internal Error
            /// <remarks>
            /// Generaly when a code try to store a unknown error code
            /// </remarks>
            /// </summary>
            [DescriptionAttribute("Internal Error")]
            InternalError = -1,
            /// <summary>
            /// Success, all ok
            /// </summary>
            [DescriptionAttribute("Success, all ok")]
            Success = 0,
            /// <summary>
            /// Fail generic
            /// </summary>
            [DescriptionAttribute("Fail generic")]
            Fail,
            /// <summary>
            /// No Data to retreive
            /// </summary>
            [DescriptionAttribute("No Data to retreive")]
            NoData,
        }
        #endregion

        #region Public
        /// <summary>
        /// 
        /// </summary>
        public static readonly int SUCCESS = 0;
        #endregion

        #region Private members
        /// <summary>
        /// Base is success
        /// </summary>
        private int m_iErrorCode = (int)ErrorCodes.Success;
        /// <summary>
        /// Error Code
        /// </summary>
        private Exception m_oApplicationException;
        /// <summary>
        /// The error message
        /// </summary>
        private string m_sErrorMessage;
        /// <summary>
        /// Error Message
        /// </summary>
        private List<string> m_lstErrorMessageParameters;
        /// <summary>
        /// Is valid or not
        /// </summary>
        private bool m_bIsValid;
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the error code.
        /// </summary>
        /// <value>The error code.</value>
        [DataMember]
        public int ErrorCode
        {
            get { return m_iErrorCode; }
            set
            {
                m_iErrorCode = value;
            }
        }
        /// <summary>
        /// Gets or sets the application exception.
        /// </summary>
        /// <value>The application exception.</value>
        [DataMember]
        public Exception ApplicationException
        {
            get { return m_oApplicationException; }
            set
            {
                m_oApplicationException = value;
                m_bIsValid = false;
            }
        }
        /// <summary>
        /// Gets or sets the error message.
        /// </summary>
        /// <value>The erro message.</value>
        [DataMember]
        public string ErrorMessage
        {
            get { return m_sErrorMessage; }
            set
            {
                m_sErrorMessage = value;
                // If no erro message the object is valid
                if (!string.IsNullOrEmpty(m_sErrorMessage))
                {
                    m_bIsValid = false;
                }
                else
                {
                    IsValid = true;
                }
            }
        }
        /// <summary>
        /// Gets or sets the error message parameters.
        /// </summary>
        /// <value>The error message parameters.</value>
        [DataMember]
        public List<string> ErrorMessageParametersList
        {
            get
            {
                if (m_lstErrorMessageParameters == null)
                {
                    m_lstErrorMessageParameters = new List<string>();
                }
                return m_lstErrorMessageParameters;
            }
            set
            {
                m_lstErrorMessageParameters = value;
            }
        }
        /// <summary>
        /// Gets or sets a value indicating whether this instance is valid.
        /// </summary>
        /// <value><c>true</c> if this instance is valid; otherwise, <c>false</c>.</value>
        [DataMember]
        public bool IsValid
        {
            get { return m_bIsValid; }
            set { m_bIsValid = value; }
        }
        #endregion

        #region Method
        /// <summary>
        /// Adds the error message parameter.
        /// </summary>
        /// <param name="param">The param.</param>
        public void AddErrorMessageParameter(string param)
        {
            if (m_lstErrorMessageParameters == null)
            {
                m_lstErrorMessageParameters = new List<string>();
            }
            m_lstErrorMessageParameters.Add(param);
        }
        /// <summary>
        /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
        /// </returns>
        public override string ToString()
        {
            string message = string.Empty;
            if (this.m_oApplicationException != null)
            {
                if (string.IsNullOrEmpty(this.m_sErrorMessage))
                {
                    message = this.m_oApplicationException.Message;
                }
                else
                {
                    message = this.m_sErrorMessage;
                }
                return string.Format("({0}): {1}",
                    message,
                    this.m_oApplicationException);
            }
            else
            {
                return string.Format("({0})",
                    this.m_sErrorMessage);
            }
        }
        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"></see> to compare with the current <see cref="T:System.Object"></see>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>; otherwise, false.
        /// </returns>
        public override bool Equals(object obj)
        {
            if (obj == null || !(obj is ReturnObject))
                return false;
            ReturnObject tmp = (obj as ReturnObject);
            return (this.IsValid.Equals(tmp.IsValid)
                && this.ErrorMessage == tmp.ErrorMessage);
        }
        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"></see>.
        /// </returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        /// <summary>
        /// Clears the return object value to its initial one
        /// </summary>
        public void Clear()
        {
            this.m_bIsValid = true;
            this.m_sErrorMessage = string.Empty;
            this.m_iErrorCode = SUCCESS;
            this.m_oApplicationException = null;
        }
        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorObject"/> class.
        /// </summary>
        public ReturnObjectEntity()
        {
            this.m_bIsValid = true;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorObject"/> class.
        /// </summary>
        /// <param name="errorMessage">The error message.</param>
        public ReturnObjectEntity(string errorMessage)
            : this(errorMessage, null)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorObject"/> class.
        /// </summary>
        /// <param name="errorMessage">The error message.</param>
        /// <param name="applicationException">The application exception.</param>
        public ReturnObjectEntity(string errorMessage, Exception applicationException)
        {
            this.m_bIsValid = false;
            this.m_sErrorMessage = errorMessage;
            this.m_oApplicationException = applicationException;
        }

        #endregion

        public int MyProperty { get; set; }
    }


    /// <summary>
    /// DATABASE TABLENAME : r_group
    /// </summary>
    [DataContract]
    public class GroupEntity : ReturnObjectEntity
    {
        #region Private members

        /// <summary>
        /// Database Identifier
        /// </summary>
        private long m_lIdentifier;

        /// <summary>
        /// The name of the group
        /// </summary>
        private string m_sName;

        /// <summary>
        /// Does the group allow the user to view
        /// </summary>
        private bool m_bCanConsult;

        /// <summary>
        /// Does the group allow the user to modify
        /// </summary>
        private bool m_bCanReorganize;

        /// <summary>
        /// Does the group give the administrator right
        /// </summary>
        private bool m_bIsAdministrator;

        /// <summary>
        /// Does the group allow the user to scann
        /// </summary>
        private bool m_bCanScann;

        /// <summary>
        /// Does the group allow the user to print
        /// </summary>
        private bool m_bCanPrint;

        /// <summary>
        /// Does the group allow the send email
        /// </summary>
        private bool m_bCanSendEmail;

        /// <summary>
        /// Does the group allow the download
        /// </summary>
        private bool m_bCanDownload;

        /// <summary>
        /// The entity associated
        /// </summary>
        private Organization m_oEntity;
        #endregion

        #region Properties
        public Organization Entity
        {
            get { return m_oEntity; }
            set { m_oEntity = value; }
        }

        public bool CanDownload
        {
            get { return m_bCanDownload; }
            set { m_bCanDownload = value; }
        }

        public bool CanPrint
        {
            get { return m_bCanSendEmail; }
            set { m_bCanSendEmail = value; }
        }

        public bool CanScann
        {
            get { return m_bCanScann; }
            set { m_bCanScann = value; }
        }

        public bool CanReorganize
        {
            get { return m_bCanReorganize; }
            set { m_bCanReorganize = value; }
        }

        public bool IsAdministratort
        {
            get { return m_bIsAdministrator; }
            set { m_bIsAdministrator = value; }
        }

        public bool CanSendEmail
        {
            get { return m_bCanSendEmail; }
            set { m_bCanSendEmail = value; }
        }
        [DataMember]
        public string Name
        {
            get { return m_sName; }
            set { m_sName = value; }
        }
        [DataMember]
        public User Owner { get; set; }

        [DataMember]
        public long Identifier
        {
            get { return m_lIdentifier; }
            set { m_lIdentifier = value; }
        }
        public bool CanConsult
        {
            get { return m_bCanConsult; }
            set { m_bCanConsult = value; }
        }
        #endregion

        public override object Clone()
        {
            throw new NotImplementedException();
        }
    }

    [DataContract]
    public class UserEntity : ReturnObjectEntity
    {
        #region Private members
        /// <summary>
        /// Database Identifier
        /// </summary>
        private long m_lIdentifier;

        [DataMember]
        public long UserId
        {
            get { return m_lIdentifier; }
            set { m_lIdentifier = value; }
        }

        /// <summary>
        /// User Login
        /// </summary>
        private string m_sLogin;

        [DataMember]
        public string Login
        {
            get { return m_sLogin; }
            set { m_sLogin = value; }
        }

        /// <summary>
        /// User password
        /// </summary>
        private string m_sPassword;
        [DataMember]
        public string Password
        {
            get { return m_sPassword; }
            set { m_sPassword = value; }
        }

        /// <summary>
        /// User first name
        /// </summary>
        private string m_sFirstName;
        [DataMember]
        public string FirstName
        {
            get { return m_sFirstName; }
            set { m_sFirstName = value; }
        }

        /// <summary>
        /// User last name
        /// </summary>
        private string m_sLastName;

        public string LastName
        {
            get { return m_sLastName; }
            set { m_sLastName = value; }
        }

        /// <summary>
        /// User email
        /// </summary>
        private string m_sEmail;

        [DataMember]
        public string Email
        {
            get { return m_sEmail; }
            set { m_sEmail = value; }
        }

        /// <summary>
        /// List of group where the user is assigned
        /// </summary>
        private List<GroupEntity> m_lstGroup;

        [Association("ListGroupEntity1", "Key", "ForeignKey")]
        [Include]
        [DataMember]
        public List<GroupEntity> GroupList
        {
            get { return m_lstGroup; }
            set
            {
                ItemEntity.SetForeignKey(value, Key);
                m_lstGroup = value;
            }
        }

        [Association("GroupEntity1", "ForeignKey1", "Key")]
        [Include]
        [DataMember]
        public GroupEntity Group
        {
            get { return m_oGroup; }
            set
            {
                ForeignKey1 = value.Key;
                m_oGroup = value;
            }
        }
        private GroupEntity m_oGroup;


        [DataMember]
        public long GroupId
        {
            get;
            set;
        }


        /// <summary>
        /// List of all user actions 
        /// </summary>
        private List<ActionHistoric> m_lstUserActionHistoric;

        public List<ActionHistoric> UserActionHistoricList
        {
            get { return m_lstUserActionHistoric; }
            set { m_lstUserActionHistoric = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        [DataMember(Name = "EntitiesList")]
        List<ClassBase> m_lstEntities;
        public IList<ClassBase> EntitiesList { get { return m_lstEntities; } set { m_lstEntities = (List<ClassBase>)value; } }

        //[DataMember(Name = "EntitiesList")]
        //List<Entity> m_lstEntities;
        //public List<Entity> EntitiesList
        //{
        //    get { return m_lstEntities; }
        //    set { m_lstEntities = value; }
        //}

        #endregion

        public override object Clone()
        {
            throw new NotImplementedException();
        }
    }
    #endregion
}
